package org.lboot.flow.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Validator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lboot.core.domain.ResponseDTO;
import org.lboot.core.exception.BusinessException;
import org.lboot.flow.event.FlowEventConsumer;
import org.lboot.flow.event.FlowEventConsumerMeta;
import org.lboot.flow.module.event.FlowCustomEvent;
import org.lboot.flow.module.event.FlowCustomEventService;
import org.lboot.flow.module.event.params.FlowCustomEventCreateParams;
import org.lboot.flow.module.event.params.FlowCustomEventQueryParams;
import org.lboot.flow.module.event.params.FlowCustomEventUpdateParams;
import org.lboot.flow.module.event.sp.FlowEventServiceProvider;
import org.lboot.jpa.utils.JpaDataUtil;

import org.lboot.starter.plugin.rsr.RsrTree;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("flow")
@Api(tags = "自定义事件")
@RsrTree("流程引擎")
@AllArgsConstructor
public class FlowCustomEventController {

    FlowCustomEventService eventService;

    List<FlowEventConsumer> consumers;

    @PostMapping("events")
    @ApiOperation(value = "事件新增")
    public ResponseDTO<Object> eventCreate(@Validated @RequestBody FlowCustomEventCreateParams params){
        FlowCustomEvent event = new FlowCustomEvent();
        // 需要有重复性校验
        List<FlowCustomEvent> events = eventService.getByEventId(params.getEventId());
        if (!events.isEmpty()){
            throw new BusinessException(HttpStatus.BAD_REQUEST,"存在重复事件ID");
        }
        BeanUtil.copyProperties(params,event, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        return ResponseDTO.succData(
                eventService.saveOne(event)
        );
    }

    @DeleteMapping("events/{id}")
    @ApiOperation(value = "事件删除")
    // @CheckRole(orPerm = "flow:event:delete")
    public ResponseDTO<Object> eventDelete(@PathVariable("id") String eventId){
        eventService.deleteOne(eventId);
        return ResponseDTO.succMsg("删除成功");
    }

    @PutMapping("events")
    @ApiOperation(value = "事件更新")
    // @CheckRole(orPerm = "flow:event:update")
    public ResponseDTO<Object> eventUpdate(@Validated @RequestBody FlowCustomEventUpdateParams params){
        FlowCustomEvent event = eventService.getOneUnwrap(params.getId());
        BeanUtil.copyProperties(params,event,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        return ResponseDTO.succData(
                eventService.updateOne(event)
        );
    }

    @GetMapping("events")
    @ApiOperation(value = "事件列表")
    public ResponseDTO<Object> eventQueryList(FlowCustomEventQueryParams params){
        Pageable pageable = JpaDataUtil.buildPageable(params);
        // 构建谓词查询
        Specification<FlowCustomEvent> spec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            if (Validator.isNotEmpty(params.getPriority())){
                Predicate p3 = cb.equal(root.get("priority").as(Integer.class),   params.getPriority());
                list.add(p3);
            }

            if (Validator.isNotEmpty(params.getStatus())){
                Predicate p4 = cb.equal(root.get("status").as(Integer.class),   params.getStatus());
                list.add(p4);
            }
            // 事件同步 异步
            if (Validator.isNotEmpty(params.getIsAsync())){
                Predicate p = cb.equal(root.get("isAsync").as(Boolean.class),   params.getIsAsync());
                list.add(p);
            }
            Predicate[] predicates = new Predicate[list.size()];
            return cb.and(list.toArray(predicates));
        };
        if (Validator.isEmpty(spec)){
            return ResponseDTO.succData(eventService.getAll(pageable));
        }
        return ResponseDTO.succData(
                eventService.getAll(pageable,spec)
        );
    }

    @GetMapping("events/{id}")
    @ApiOperation(value = "事件查询")
    public ResponseDTO<Object> eventQuery(@PathVariable("id") String id){
        return ResponseDTO.succData(eventService.getOneUnwrap(id));
    }

    // 获取事件消费者列表
    @GetMapping("events/{eventId}/consumers")
    @ApiOperation(value = "事件消费者查询")
    public ResponseDTO<Object> eventConsumers(@PathVariable("eventId") String eventId){
        List<FlowEventConsumerMeta> metas = new ArrayList<>();
        List<FlowEventServiceProvider> serviceProviders = new ArrayList<>();
        // 获取内部服务实现
        for (FlowEventConsumer consumer: consumers){
            if (consumer.eventId().equals(eventId)){
                FlowEventServiceProvider sp = new FlowEventServiceProvider();
                sp.setEventId(eventId);
                sp.setServiceId(consumer.consumerId());
                sp.setServiceName(consumer.consumerName());
                sp.setPriority(consumer.priority());
                // 补全数据
                sp = consumer.meta().injectMeta(sp);
                serviceProviders.add(sp);
            }
        }
        // 获取服务注册中心实现

        return ResponseDTO.succData(serviceProviders);
    }
}
